﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.IO;

namespace SpeedTestServerSetup
{
	public partial class Page3 : WizardPage
	{
		private Data data = null;
        string sqlPath = Path.Combine(Application.StartupPath, "SQL");
		private string connString = String.Empty;
		private bool taskCompleted = false;

        public override event StateChangeEvent ReadyStateChanged;
        
        public Page3()
		{
			InitializeComponent();
		}

        //unused for this page
        public override void LeavePage(WizardEvents e){	}
        public override void EnterPage(WizardEvents e)
        { 
            //check config for completed tasks
			if (taskCompleted && ReadyStateChanged != null && e.Direction == WizardDirection.Next)
            {
				ReadyStateChanged.Invoke(true);
			}
        }


		private bool AttemptConnect(string database)
		{
			connString = ConnectionString.Build(
				ConfigurationManager.AppSettings.Get("PGServerName"),
				ConfigurationManager.AppSettings.Get("PGPort"),
				ConfigurationManager.AppSettings.Get("PGUserName"),
				ConfigurationManager.AppSettings.Get("PGPassword"),
                database); //take the default database

            data = new Data(connString);
            return data.Connect();

		}

		private bool AttemptCreateUser()
		{
            string sqlFilePath = Path.Combine(sqlPath, "CreateSuperuser.sql");
            return data.PutDataFromFile(sqlFilePath);
		}

		private bool AttemptCreateDB()
		{
            string sqlFilePath = Path.Combine(sqlPath, "CreateDatabase.sql");
            return data.PutDataFromFile(sqlFilePath);
		}

		private bool AttemptCreateTables()
		{
            string sqlFilePath = Path.Combine(sqlPath, "CreateTables.sql");
            return data.PutDataFromFile(sqlFilePath);
		}

		private bool AttemptAddData()
		{
            string sqlFilePath = Path.Combine(sqlPath, "InsertRequiredData.sql");
            if (data.PutDataFromFile(sqlFilePath))
            {
                sqlFilePath = Path.Combine(sqlPath, "InsertReportData.sql");
                return data.PutDataFromFile(sqlFilePath);
            }

            return false;
		}

        private bool AttemptInstallFunctions()
        {
            string sqlFilePath = Path.Combine(sqlPath, "tablefunc.sql");
            return data.PutDataFromFile(sqlFilePath);
        }

        private bool UpdateWebConfig()
        {
			string configPath = Path.Combine(Application.StartupPath, "InstallationFiles\\SpeedTestReports");
			string filePath = Path.Combine(configPath, "Web.config");
			ConfigFile config = new ConfigFile(filePath);
			config.SetValue("configuration/appSettings/add[@key='PGSConnString']", "value", connString);
			config.Save();

            return true;
        }

		private enum TaskStatus
		{
			Success,
			Failure,
			NotRun
		}

		private void SetPic(PictureBox pic, TaskStatus status)
		{

			switch (status)
			{
				case TaskStatus.NotRun:		//no pic
					pic.Image = null;
					break;
				case TaskStatus.Success:	//pic 1
					pic.Image = imageStatuses.Images[1];
					break;
				case TaskStatus.Failure:	//pic 0
					pic.Image = imageStatuses.Images[0];
					break;
				default:
					pic.Image = null;
					break;
			}
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            //this should probably be on a background worker thread

            DialogResult res = MessageBox.Show(this, "This utility is intended for new installations only.\nAny existing Speed Test database or user will be deleted.\nAre you sure you want to proceed", "Confirm", MessageBoxButtons.YesNo);
            if (res == DialogResult.Yes)
            {
                this.Cursor = Cursors.WaitCursor;
                PerformSetupTasks();
                this.Cursor = Cursors.Default;
				taskCompleted = true;
            }
            else
            {
                MessageBox.Show("Speed Test may not work properly is the databases are not installed.\nProceed at your own risk.");
                if (ReadyStateChanged != null)
                {
                    ReadyStateChanged.Invoke(true);
					taskCompleted = true;
                }
            }
        }

        private bool AttemptCleanup()
        {
            string dropDBStatement = "DROP DATABASE IF EXISTS speedtest;";
            string dropUserStatement = "DROP USER speedtestadmin;";
            if(data.PutData(dropDBStatement))
            {
                try
                {
                    data.PutData(dropUserStatement);
                }
                catch
                {
                    return true;    //we don't care if this succeeeds.
                }
                return true;
            }
            return false;
        }

        private void PerformSetupTasks()
        {

            if (AttemptConnect(String.Empty)) 
            {
                ConfigurationManager.AppSettings.Set("PGConnected", "true");
                SetPic(picConnect, TaskStatus.Success); 
            }
            else 
            {
                ConfigurationManager.AppSettings.Set("PGConnected", "false");
                SetPic(picConnect, TaskStatus.Failure);
                return;            
            }

            if (!AttemptCleanup()) { return; }

            if (AttemptCreateUser()) 
            {
                ConfigurationManager.AppSettings.Set("PGUserCreated", "true");
                SetPic(picCreateUser, TaskStatus.Success); 
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGUserCreated", "false");
                SetPic(picCreateUser, TaskStatus.Failure);
                return;
            }

            if (AttemptCreateDB()) 
            {
                ConfigurationManager.AppSettings.Set("PGDatabaseCreated", "true");
                SetPic(picCreateDB, TaskStatus.Success); 
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGDatabaseCreated", "false");
                SetPic(picCreateDB, TaskStatus.Failure);
                return;
            }

            //Reset Database connection to new database
            data.Disconnect();
            data = null;
            AttemptConnect("speedtest");

            if (AttemptCreateTables()) 
            {
                ConfigurationManager.AppSettings.Set("PGTablesCreated", "true");
                SetPic(picCreateTables, TaskStatus.Success); 
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGTablesCreated", "false");
                SetPic(picCreateTables, TaskStatus.Failure);
                return;
            }

            if (AttemptAddData()) 
            {
                ConfigurationManager.AppSettings.Set("PGDataAdded", "true");
                SetPic(picAddData, TaskStatus.Success); 
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGDataAdded", "false");
                SetPic(picAddData, TaskStatus.Failure);
                return;
            }

            if (AttemptInstallFunctions()) 
            {
                ConfigurationManager.AppSettings.Set("PGFunctionsInstalled", "true");
                SetPic(picInstallFunctions, TaskStatus.Success);
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGFunctionsInstalled", "false");
                SetPic(picInstallFunctions, TaskStatus.Failure);
                return;
            }

            if (UpdateWebConfig()) 
            {
                ConfigurationManager.AppSettings.Set("PGConfigUpdated", "true");
                SetPic(picUpdateWebConfig, TaskStatus.Success); 
            }
            else
            {
                ConfigurationManager.AppSettings.Set("PGConfigUpdated", "false");
                SetPic(picUpdateWebConfig, TaskStatus.Failure);
                return;
            }

            if (ReadyStateChanged != null)
            {
                ReadyStateChanged.Invoke(true);
            }
        }
	}
}
